package com.voice.server.service.impl;

import com.voice.server.entity.Function;
import com.voice.server.entity.Role;
import com.voice.server.entity.User;
import com.voice.server.entity.UserRole;
import com.voice.server.enums.ResultEnum;
import com.voice.server.enums.UserTypeEnum;
import com.voice.server.exception.SystemException;
import com.voice.server.input.RegisterRequest;
import com.voice.server.input.ResetPasswordRequest;
import com.voice.server.input.SendCodeRequest;
import com.voice.server.input.UserQuery;
import com.voice.server.repository.*;
import com.voice.server.service.UserService;
import com.wangjiacai.hqlQuery.service.impl.BaseServiceImpl;
import com.wangjiacai.hqlQuery.util.HqlUtil;
import com.wangjiacai.utils.sms.SmsCodeSender;
import com.wangjiacai.utils.utils.RandomStringUtils;
import com.wangjiacai.utils.utils.SmsCodeUtil;
import com.wangjiacai.utils.web.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.List;
/*
 * @auther: wangjiacai
 *
 * @create: 2019-01-27 18:09:41
 */
@Service
public class UserServiceImpl extends BaseServiceImpl implements UserService {

    private Role genenalUser;

    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private RedisService redisService;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private RoleRepository roleRepository;
    @Autowired
    private UserRoleRepository userRoleRepository;
    @Autowired
    private RoleFunctionRepository roleFunctionRepository;
    @Autowired
    private FunctionRepository functionRepository;
    @Autowired
    private SmsCodeSender smsCodeSender;

    @Override
    public User login(String phone, String password) {
       User user=userRepository.findByPhone(phone);
       if(user==null) throw new SystemException(ResultEnum.UserNamePasswordError);
       if(!passwordEncoder.matches(password,user.getPassword()))
           throw new SystemException(ResultEnum.UserNamePasswordError);
       return user;
    }

    @Override
    public void registerRequest(RegisterRequest registerRequest) {
        SmsCodeUtil.validCode(redisService,registerRequest.getPhone(),registerRequest.getCode());
        if(userRepository.findByPhone(registerRequest.getPhone())!=null){
            throw new SystemException(ResultEnum.PhoneExist);
        }
        User user=new User();
        user.setPhone(registerRequest.getPhone());
        user.setPassword(passwordEncoder.encode(registerRequest.getPassword()));
        user.setUserType(UserTypeEnum.User.getCode());
        userRepository.save(user);
        if(genenalUser==null){
            genenalUser=roleRepository.findByName(UserTypeEnum.User.getMessage());
        }
        UserRole userRole=new UserRole();
        userRole.setUserId(user.getId());
        userRole.setRoleId(genenalUser.getId());
        userRoleRepository.save(userRole);
    }


    @Override
    public List<Function> findFunctionById(String userId) {
        List<String> roleIds=userRoleRepository.findRoleIdByUserId(userId);
        if(roleIds==null||roleIds.size()==0) return null;
        List<String> functionIds=roleFunctionRepository.findFunctionIdByRoleIdIn(roleIds);
        if(functionIds==null||functionIds.size()==0) return null;
        List<Function> functions=functionRepository.findByIdInOrderByBh(functionIds);
        return functions;
    }

    @Override
    public User findUserById(String userId) {
        return userRepository.getOne(userId);
    }

    @Override
    public void sendSmsCode(SendCodeRequest sendCodeRequest) {
        String code= RandomStringUtils.randomNumeric(6);
        redisService.set(sendCodeRequest.getPhone(),code,900);
        smsCodeSender.send(String.valueOf(sendCodeRequest.getArea()),sendCodeRequest.getPhone(),code);
    }

    @Override
    public void resetPassword(ResetPasswordRequest resetPasswordRequest) {
        SmsCodeUtil.validCode(redisService,resetPasswordRequest.getPhone(),resetPasswordRequest.getCode());
        User user=userRepository.findByPhone(resetPasswordRequest.getPhone());
        if(user==null) throw new SystemException(ResultEnum.PhoneNotExist);
        user.setPassword(passwordEncoder.encode(resetPasswordRequest.getPassword()));
        userRepository.save(user);
    }

    @Override
    public long getUserListNum(UserQuery userQuery) {
        return this.count(HqlUtil.getCountHql(userQuery),userQuery);
    }

    @Override
    public List<User> getUserList(UserQuery userQuery, Pageable pageable) {
        return this.find(HqlUtil.getQueryHql(userQuery),userQuery,pageable,User.class);
    }

}
